/*
 * @Author       : Zhao Lvhua zhaolh@linkcharging.com
 * @Date         : 2024-08-02 13:47:02
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:12:39
 * @FilePath     : \openchaoji-corelib\shared\src\OpenChaoJi_utility_transport_gbt27930_a_private.h
 * @Description  : GBT27930 B类系统传输层具体实现，包括需要确认长消息、需要确认短消息、不需要确认的短消息的发送，接收处理
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */


#ifndef OPENCHAOJI_TRANSPORT_SYSTEM_A_PRIVATE_H
#define OPENCHAOJI_TRANSPORT_SYSTEM_A_PRIVATE_H

#include "../include/OpenChaoJi_shared.h"

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)

//ack type defintions
/*
* @brief: ack type defintions
*/
#define PGN_TPCM	  (0xEC00)//传输协议——连接管理（TP.CM）
#define PGN_TPDT	  (0xEB00)//传输协议——数据传送（TP.DT）

/*
* @brief: ack type defintions
*/
#define TPCM_RTS 	    	(0x10)//请求发送
#define TPCM_CTS 	    	(0x11)//应答发送
#define TPCM_EndACK   		(0x13)//发送结束应答
#define TPCM_ABORT   		(0xff)//传输中止
#define TPCM_INVALID_VALUE	(0xee)//



/*
* @brief: 消息通信状态定义
* ChaoJi communication states defintions.
*/
enum cj_tran_gbt27930_a_state{

	//definition for RSM sending state
	RSM_S0_IDLE	= 0,            //空闲
	RSM_S1_SEND_ING,            //发送中
	RSM_S2_SEND_END,            //发送结束

	//definition for LM sending state
	LM_SEND_IDLE	= 10,       //空闲
	LM_SEND_S0_ESTB_CONN,       //建立链接
	LM_SEND_S1_DATA_TRAN,       //数据传输中
	LM_SEND_S2_AWAIT_RESP_ACK,  //等待ACK
	LM_SEND_S3_AWAIT_FIN_ACK,   //等待结束ACK
	LM_SEND_S4_CLOSE_CONN,      //关闭链接

	LM_RECV_S0_IDLE	= 20,       //空闲
	LM_RECV_S1_DATA_RECEIVING,  //数据接收中
	LM_RECV_S2_CLOSE_CONN,      //关闭链接
};


/*
* @brief: B类系统不需要确认消息控制块定义
*/
struct OpenChaoJi_gbt27930_a_urmcb
{
	int tag;

    int dummy;
	void * param;
	uint8_t port;
	uint8_t src_addr;
	uint8_t dest_addr;

	uint32_t pgn;
	struct can_pdu sm_recv_buf;
	uint8_t sm_recved_flag;	// Received flag.

	int (* can_output_func)(void * param, const struct can_pdu * send_pdu);
    int (* can_input_func)(void * param, struct can_pdu * recv_pdu);
};

/*
* @brief: A类系统需要确认消息控制块定义
*/
struct OpenChaoJi_gbt27930_a_rmcb
{
	int tag;

    int dummy;
	void * param;
	uint8_t port;
	uint8_t src_addr;
	uint8_t dest_addr;

	//需要确认长消息接收定义
	enum cj_tran_gbt27930_a_state lm_recv_state;// Send states.
    uint8_t rcved_ack_flag;	//0:SM_ACK 1:LM_ACK 2:LM_NACK 3:LM_EndACK
    uint32_t lm_recv_pgn;

    uint8_t lm_recv_no;    //为待接收信息帧帧序号
    uint8_t lm_recv_num;   //为当前请求已接收有效数据帧的帧数。

	uint8_t lm_recved_tfra;//为已接收有效数据帧的总帧数

    uint8_t lm_tfra;  //为长消息组成应用层消息结构的总帧数
    uint16_t lm_recv_tbytes;  //为长消息总的接收字节数
	uint8_t* lm_recv_buf;

	uint8_t lm_recv_err_cnt;//为接收信息帧超时次数计数器

	uint32_t lm_recv_lms_t2_intvl_ms;
	uint32_t lm_recv_lms_t2_tick;//为接收信息帧超时计时器。

	uint32_t lm_recv_lms_t3_intvl_ms;
	uint32_t lm_recv_lms_t3_tick;//为长消息传输超时计时器，发送第一帧报文开启
	uint8_t lm_recv_k;//为接收方单次能接收的数据帧的帧数(取接收能力和剩余发送帧的较小值),
    uint8_t lm_recv_n;  //为本次待接收起始帧序号（长消息应答确认帧）
    uint8_t lm_recv_active_abort;//接收主动中止
    uint8_t lm_recved_flag;

	//需要确认长消息发送定义
    enum cj_tran_gbt27930_a_state lm_send_state;// Send states.
    enum OpenChaoJi_utility_transport_MsgSendResult lm_send_result;

	uint8_t* lm_send_buf;	//缓存，发送时需要申请空间，发送完成后要释放内存
	uint8_t lm_send_tfra;//长消息发送总帧数
	uint16_t lm_send_tbytes;//为长消息组成应用层消息结构的总字节数
	uint8_t lm_send_cnt;//为一次传输中发送帧计数器，初始值为0,每发送完成一帧，计数器加1
	uint32_t lm_send_pgn;

	uint8_t lm_resend_cnt;
	uint8_t lm_send_active_abort;//发送主动中止

	uint32_t lm_send_lms_t1_intvl_ms;
	uint32_t lm_send_lms_t1_tick;

	uint32_t lm_send_lms_t2_intvl_ms;
	uint32_t lm_send_lms_t2_tick;

	uint32_t lm_send_lms_t3_intvl_ms;
	uint32_t lm_send_lms_t3_tick;

	uint8_t	lm_ack_startframe_idx;//长消息ack内容:待接收起始帧序号
	uint8_t	lm_ack_totalframe_nums;//长消息ack内容:待接收总帧数
	uint8_t pause_flag;		// Transfer pause.

	int (* can_output_func)(void * param, const struct can_pdu * send_pdu);
    int (* can_input_func)(void * param, struct can_pdu * recv_pdu);
};


/*内部函数声明*/
int16_t gbt27930_a_rlm_do_connect(struct OpenChaoJi_gbt27930_a_rmcb * rmcb);//长消息发送连接
int16_t gbt27930_a_rlm_sent_data(struct OpenChaoJi_gbt27930_a_rmcb * rmcb, uint8_t frame_idx);
int16_t gbt27930_a_rlm_sent_nack(struct OpenChaoJi_gbt27930_a_rmcb * rmcb);//长消息NACK发送

int16_t gbt27930_a_rlm_send_cts(struct OpenChaoJi_gbt27930_a_rmcb * rmcb);
int16_t gbt27930_a_rlm_sent_nack(struct OpenChaoJi_gbt27930_a_rmcb * rmcb);
int16_t gbt27930_a_rlm_send_endofack(struct OpenChaoJi_gbt27930_a_rmcb * rmcb);

/*
* @brief: gbt27930 A类系统需要确认长消息的发送处理过程
* @param {can_pdu *} pdu 需要发送的数据帧
* @param {OpenChaoJi_gbt27930_a_rmcb} *rmcb 可靠确认消息体的指针，包含必要的环境信息。
* @return {*} 成功返回0，失败返回-1。
*/
int16_t OpenChaoJi_transport_gbt27930_a_rlm_send_process(struct can_pdu * pdu,struct OpenChaoJi_gbt27930_a_rmcb * rmcb);

/*
* @brief: gbt27930 A类系统需要确认长消息的接收处理过程
* @param {can_pdu *} pdu 接收到数据帧
* @param {OpenChaoJi_gbt27930_a_rmcb} *rmcb 可靠确认消息体的指针，包含必要的环境信息。
* @return {*} 成功返回0，失败返回-1。
*/
int16_t OpenChaoJi_transport_gbt27930_a_rlm_recv_process(struct can_pdu * pdu, struct OpenChaoJi_gbt27930_a_rmcb * rmcb);

#endif

#endif // OPENCHAOJI_TRANSPORT_SYSTEM_B__H.

